package model

import (
	"reflect"
	"strings"

	Log "github.com/cihub/seelog"
)

var (
	dbEntityInfo = make(map[string]interface{}) //注册的数据库实体类
	dbTableInfo  = make(map[string]*TableInfo)  //注册的数据库表信息
)

//数据信息注解
type TableInfo struct {
	GsDbName          string `json:"sDbName"`          //所在数据库名称
	GsTableName       string `json:"sTableName"`       //所在数据库表表名称
	GsKeyName         string `json:"sKeyName"`         //表主键名称
	GiKeyLen          int    `json:"iKeyLen"`          //主键长度
	GbAutoKey         bool   `json:"bAutoKey"`         //是否自增主键
	GbHasPid          bool   `json:"bHasPid"`          //是否存在sPid
	GbHasPath         bool   `json:"bHasPath"`         //是否存在sPath
	GbHasRecordKey    bool   `json:"bHasRecordKey"`    //是否存在sRecordKey
	GbHasMemo         bool   `json:"bHasMemo"`         //是否存在sMemo
	GbHasCreator      bool   `json:"bHasCreator"`      //是否存在sCreator
	GbHasCreateDate   bool   `json:"bHasCreateDate"`   //是否存在dCreateDate
	GbHasModifieder   bool   `json:"bHasModifieder"`   //是否存在sModifieder
	GbHasModifiedDate bool   `json:"bHasModifiedDate"` //是否存在dModifiedDate
	GbHasState        bool   `json:"bHasState"`        //是否存在iState
	GbHasIndex        bool   `json:"bHasIndex"`        //是否存在iIndex
	GbHasVersion      bool   `json:"bHasVersion"`      //是否存在iVersion
	GbHasPassword     bool   `json:"bHasPassword"`     //是否存在sPassword
	GbHasSign         bool   `json:"bHasSign"`         //是否存在sSign
}

//注册数据库实体类结构体
func (t TableInfo) RegisterEntity(name string, entity interface{}) {
	_, ok := dbEntityInfo[name]
	if ok {
		Log.Error("注册数据库实体类结构体重复:" + name)
		return
	}

	dbEntityInfo[name] = entity
}

//取指定数据库实体类信息
func (t TableInfo) GetEntity(name string) interface{} {
	entity, ok := dbEntityInfo[name]
	if !ok {
		Log.Error("查找的数据库实体类结构体不存在:" + name)
		return nil
	}

	result := reflect.New(reflect.TypeOf(entity).Elem())

	return &result
}

//注册数据库表信息
func (t TableInfo) RegisterTableInfo(name string, tableInfo *TableInfo) {
	_, ok := dbTableInfo[name]
	if ok {
		Log.Error("注册数据库实体类结构体重复:" + name)
		return
	}

	dbTableInfo[name] = tableInfo
}

//取指定数据库表信息
func (t TableInfo) GetTableInfo(name string) *TableInfo {
	tableInfo, ok := dbTableInfo[name]
	if !ok {
		Log.Error("查找的数据库实体类结构体不存在:" + name)
		return nil
	}

	return tableInfo
}

//取指定数据库表信息
func (t TableInfo) GetByEntity(entity interface{}) *TableInfo {
	var rve reflect.Value

	typeOf := reflect.TypeOf(entity)  //通过反射获取type定义
	if typeOf.Kind() == reflect.Ptr { //是否指针类型
		rve = reflect.ValueOf(entity).Elem() // 取得struct变量的指针
	} else if "reflect.Value" == typeOf.String() {
		rve = entity.(reflect.Value)
	} else {
		rve = reflect.ValueOf(entity)
	}

	entityName := rve.Type().Name() //取实体名称

	if !strings.HasSuffix(entityName, "Base") {
		entityName = entityName + "Base"
	}

	return t.GetTableInfo(entityName)
}

//取指定数据库表的字段名集合
func (t TableInfo) GetColumnNames(entity interface{}) []string {
	var rve reflect.Value

	typeOf := reflect.TypeOf(entity)  //通过反射获取type定义
	if typeOf.Kind() == reflect.Ptr { //是否指针类型
		rve = reflect.ValueOf(entity).Elem() // 取得struct变量的指针
	} else if "reflect.Value" == typeOf.String() {
		rve = entity.(reflect.Value)
	} else {
		rve = reflect.ValueOf(entity)
	}

	method := rve.MethodByName("BaseColumnNames")
	if !method.IsValid() {
		return []string{}
	}

	params := make([]reflect.Value, 0)

	return (method.Call(params)[0]).Interface().([]string)
}
